import base64
import json
import pickle

import django_redis
from django.http import JsonResponse
from django.views import View

from apps.goods.models import SKU


# Create your views here.


class CartsView(View):

    def post(self, request):
        data = json.loads(request.body.decode())

        sku_id = data.get('sku_id')
        count = data.get('count')

        if not all([sku_id, count]):
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        if isinstance(count, int):
            count = int(count)
        else:
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        user = request.user
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})

        if user.is_authenticated:
            redis_client = django_redis.get_redis_connection('carts')

            cart_count = redis_client.hget(f'{user.id}_carts', sku_id)
            if cart_count:
                count += int(cart_count)

            redis_client.hset(f'{user.id}_carts', sku_id, count)
        else:
            carts = request.COOKIES.get('carts')
            if carts:
                carts = pickle.loads(base64.b64decode(carts))
            else:
                carts = {}

            if sku_id in carts:
                cart_count = carts[sku_id]['count']
                count += cart_count

            carts[sku_id] = {
                'count': count,
                'selected': False
            }
            carts = base64.b64encode(pickle.dumps(carts)).decode()
            response.set_cookie('carts', carts, max_age=6400 * 24 * 30)

        return response

    def get(self, request):

        user = request.user
        if user.is_authenticated:
            redis_client = django_redis.get_redis_connection('carts')

            sku_id_counts = redis_client.hgetall(f'{user.id}_carts')
            cart_selected = redis_client.smembers(f'{user.id}_selected')

            carts = {}

            for sku_id, count in sku_id_counts.items():
                carts[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in cart_selected
                }

        else:
            carts = request.COOKIES.get('carts')
            if carts:
                carts = pickle.loads(base64.b64decode(carts))
            else:
                carts = {}

        cart_skus = []

        sku_ids = carts.keys()

        skus = SKU.objects.filter(id__in=sku_ids)

        for sku in skus:
            cart_skus.append(
                {
                    'id': sku.id,
                    'name': sku.name,
                    'count': carts.get(sku.id).get('count'),
                    'selected': carts.get(sku.id).get('selected'),
                    'default_image_url': sku.default_image.url,
                    'price': sku.price,
                    'amount': sku.price * carts.get(sku.id).get('count'),
                }
            )

        return JsonResponse({'code': 0, 'errmsg': 'OK', 'cart_skus': cart_skus})

    def put(self, request):

        data = json.loads(request.body.decode())

        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected')

        if not all([sku_id, count]) or selected is None:
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        try:
            SKU.objects.get(id=sku_id)

        except SKU.DoesNotExist:
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        if isinstance(count, int):
            count = int(count)
        else:
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        if not isinstance(selected, bool):
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        user = request.user

        if user.is_authenticated:
            redis_client = django_redis.get_redis_connection('carts')
            sku_id_count = redis_client.hget(f'{user.id}_carts', sku_id)

            if not sku_id_count:
                return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

            redis_client.hset(f'{user.id}_carts', sku_id, count)

            if selected:
                redis_client.sadd(f'{user.id}_selected', sku_id)
            else:
                redis_client.srem(f'{user.id}_selected', sku_id)

            cart_sku = {
                'count': int(redis_client.hget(f'{user.id}_carts', sku_id)),
                'selected': str(sku_id).encode() in redis_client.smembers(f'{user.id}_selected'),
            }

            return JsonResponse({'code:': 0, 'errmsg': 'ok', 'cart_sku': cart_sku})

        else:
            carts = request.COOKIES.get('carts')
            if carts is None:
                return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

            carts = pickle.loads(base64.b64decode(carts))

            if sku_id not in carts:
                return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

            carts[sku_id]['count'] = count
            carts[sku_id]['selected'] = selected

            cart_sku = {
                'count': carts[sku_id]['count'],
                'selected': carts[sku_id]['selected'],
            }

            carts = base64.b64encode(pickle.dumps(carts)).decode()

            response = JsonResponse({'code:': 0, 'errmsg': 'ok', 'cart_sku': cart_sku})
            response.set_cookie('carts', carts, max_age=6400 * 24 * 30)
            return response

    def delete(self, request):
        data = json.loads(request.body.decode())

        sku_id = data.get('sku_id')

        if sku_id is None:
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

        user = request.user

        if user.is_authenticated:
            redis_client = django_redis.get_redis_connection('carts')
            sku_id_count = redis_client.hget(f'{user.id}_carts', sku_id)

            if not sku_id_count:
                return JsonResponse(data={'code': 400, 'errmsg': '参数错误'})

            redis_client.hdel(f'{user.id}_carts', sku_id)

            redis_client.srem(f'{user.id}_selected', sku_id)

            return JsonResponse(data={'code': 0, 'errmsg': 'ok'})

        else:
            carts = request.COOKIES.get('carts')
            carts = pickle.loads(base64.b64decode(carts))

            del carts[sku_id]

            carts = base64.b64encode(pickle.dumps(carts)).decode()

            response = JsonResponse(data={'code': 0, 'errmsg': 'ok'})

            response.set_cookie('carts', carts, max_age=3600 * 24 * 30)

            return response
